package com.psq.core.common.base

import android.annotation.SuppressLint
import android.app.Activity
import android.app.Dialog
import android.content.DialogInterface
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.Window
import android.view.WindowManager
import android.widget.RelativeLayout
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentManager
import cn.wufuqi.convertmainthread.ConvertMainThread
import com.psq.core.common.CommonAppContext

abstract class BaseDialogFragment : DialogFragment, IPattern {

    /**
     * TAG
     */
    val TAG = javaClass.simpleName

    private var handler: Handler? = null

    private var isOpenShow = false


    private lateinit var mDialog: Dialog


    private var mDefaultWidth: Int
    private var mDefaultHeight: Int
    private var mDefaultGravity: Int

    /**
     * 根view
     */
    private lateinit var mRootView: RelativeLayout

    /**
     * 内容view，这个才是xml的布局
     */
    private lateinit var mContentView: View

    /**
     * 隐藏的回调
     */
    open var mHideCallback: (() -> Unit)? = null


    private var mCancelable = true //默认点击物理按键可取消

    private var mCanceledOnTouchOutside = true //默认点击外部可取消

    /**
     * 是否显示 对话框的半透明黑色背景
     */
    open var isShowDialogTransparentBg = true


    constructor() : this(
        WindowManager.LayoutParams.WRAP_CONTENT,
        WindowManager.LayoutParams.WRAP_CONTENT,
        Gravity.CENTER
    )

    @SuppressLint("ValidFragment")
    constructor(width: Int, height: Int, gravity: Int) {
        mDefaultWidth = width
        mDefaultHeight = height
        mDefaultGravity = gravity
    }


    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        initStatusBar()

        mRootView = RelativeLayout(context)
        mRootView.layoutParams = ViewGroup.LayoutParams(
            ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT
        )

        container?.addView(mRootView)

        mRootView.addView(inflateView(inflater, mRootView, getLayoutResId()))

        doBeforeView(savedInstanceState)
        initView(savedInstanceState)
        doAfterView(savedInstanceState)
        initViewAndDataInterval()
        beforeInitData(savedInstanceState)
        initData(savedInstanceState)
        afterInitData(savedInstanceState)
        return mRootView
    }


    open fun inflateView(inflater: LayoutInflater, container: ViewGroup?, layoutResID: Int): View {
        mContentView = inflater.inflate(layoutResID, container, false)
        return mContentView
    }


    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        mDialog = super.onCreateDialog(savedInstanceState)
        beforeInitWindow()
        initWindow()
        afterInitWindow()
        //初始化
        mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
        mDialog.setCanceledOnTouchOutside(mCanceledOnTouchOutside)
        mDialog.setCancelable(mCancelable)
        val window: Window? = mDialog.window
        if (null != window) {
            window.decorView.setPadding(0, 0, 0, 0)
            window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
            val lp = window.attributes
            lp.width = mDefaultWidth
            lp.height = mDefaultHeight
            lp.gravity = mDefaultGravity
            lp.windowAnimations = getAnimationType()
            window.attributes = lp
        }
        mDialog.setOnKeyListener { _, _, _ -> !mCancelable }
        afterCreateDialog(mDialog)
        return mDialog
    }

    override fun onStart() {
        super.onStart()
        if (!isShowDialogTransparentBg) {
            dialog.window?.attributes?.dimAmount = 0f
            dialog.window?.attributes = dialog.window?.attributes
        }
    }

    open fun afterCreateDialog(dialog: Dialog) {}

    /**
     * 在初始化Window之前调用
     */
    open fun beforeInitWindow() {}

    override fun getDialog(): Dialog {
        return mDialog
    }

    /**
     * 初始化window
     */
    open fun initWindow() {
        this.dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
    }

    /**
     * 在初始化Window之前调用
     */
    open fun afterInitWindow() {}


    /**
     * 获取 dialog  动画方式
     */
    open fun getAnimationType(): Int = android.R.style.Animation_Dialog


    /**
     * 初始化数据
     */
    open fun initData(savedInstanceState: Bundle?) {}

    /**
     * 在初始化数据之后调用
     */
    open fun afterInitData(savedInstanceState: Bundle?) {}

    /**
     * xml 布局的view
     */
    open fun getContentView() = mContentView

    /**
     * 获取根View节点
     */
    open fun getRootView(): View {
        return mRootView
    }


    /**
     * 设置隐藏时的回调
     */
    open fun setHideCallback(callback: (() -> Unit)?) {
        mHideCallback = callback
    }

    /**
     * 设置位置
     * @param gravity
     */
    open fun setGravity(gravity: Int) {
        mDefaultGravity = gravity
    }

    /**
     * 设置宽
     * @param width
     */
    open fun setWidth(width: Int) {
        mDefaultWidth = width
    }

    /**
     * 设置高
     * @param height
     */
    open fun setHeight(height: Int) {
        mDefaultHeight = height
    }


    /**
     * 视图和数据的间隔带
     */
    open fun initViewAndDataInterval() {}

    /**
     * 在初始化数据之前调用
     */
    open fun beforeInitData(savedInstanceState: Bundle?) {}

    override fun initStatusBar() {

    }

    override fun doBeforeView(savedInstanceState: Bundle?) {
    }

    override fun initView(savedInstanceState: Bundle?) {
    }

    override fun doAfterView(savedInstanceState: Bundle?) {
    }

    override fun showProgressBar() {
    }

    override fun hideProgressBar() {
    }


    /**
     * 设置点击返回按钮是否可取消
     *
     * @param cancelable
     */
    override fun setCancelable(cancelable: Boolean) {
        mCancelable = cancelable
    }

    /**
     * 设置点击外部是否可取消
     *
     * @param canceledOnTouchOutside
     */
    open fun setCanceledOnTouchOutside(canceledOnTouchOutside: Boolean) {
        mCanceledOnTouchOutside = canceledOnTouchOutside
    }


    open fun show() {
        val topActivity = CommonAppContext.getInstance().getTopActivity()
        topActivity?.let {
            if (topActivity is AppCompatActivity) {
                show(topActivity)
            } else if (topActivity is Activity) {
                showActivity(topActivity)
            }
        }
    }

    /**
     * 避免抛出java.lang.IllegalStateException
     */
    override fun show(manager: FragmentManager, tag: String?) {
        if (isAdded) {
            return
        }
        ConvertMainThread.runOnUiThread {
            val mClass = getDialogFragmentClass(this::class.java)
            val dismissed = mClass?.getDeclaredField("mDismissed")
            dismissed?.isAccessible = true
            dismissed?.set(this, false)
            val shownByMe = mClass?.getDeclaredField("mShownByMe")
            shownByMe?.isAccessible = true
            shownByMe?.set(this, true)
            val ft = manager.beginTransaction()
            ft.add(this, tag)
            ft.commitAllowingStateLoss()
        }
    }

    /**
     * 获取  DialogFragment 的 class 以便于更改属性值
     */
    private fun getDialogFragmentClass(clazz: Class<*>?): Class<*>? {
        if (clazz == null) {
            return null
        }
        if (clazz.simpleName == "DialogFragment") {
            return clazz
        }
        return getDialogFragmentClass(clazz.superclass)
    }


    /**
     * 是否正在显示
     */
    open fun isShow() = isAdded && isOpenShow


    /**
     * 通过activity 显示
     */
    open fun show(activity: AppCompatActivity) {
        isOpenShow = true
        show(activity.supportFragmentManager, TAG + System.currentTimeMillis())
    }

    open fun showActivity(activity: Activity) {
        isOpenShow = true
        show(
            (activity as FragmentActivity).supportFragmentManager,
            TAG + System.currentTimeMillis()
        )
    }

    /**
     * 通过Fragment 显示
     */
    open fun show(fragment: Fragment) {
        isOpenShow = true
        show(fragment.childFragmentManager, TAG + System.currentTimeMillis())
    }


    /**
     * 隐藏对话框  避免抛出java.lang.IllegalStateException
     */
    open fun hide() {
        isOpenShow = false
        if (isAdded) {
            runOnUiThread {
                dismissAllowingStateLoss()
            }
        }
    }

    /**
     * 切换到主线程
     */
    override fun runOnUiThread(action: Runnable) {
        ConvertMainThread.runOnUiThread { action.run() }
    }

    /**
     * 转到主线程执行
     * 跟生命周期相关，被销毁则不会被执行
     */
    override fun runLifecycleOnUiThread(action: Runnable) {
        if (Thread.currentThread() !== Looper.getMainLooper().thread) {
            handler?.post(action)
        } else {
            handler?.let {
                action.run()
            }
        }
    }

    override fun onDismiss(dialog: DialogInterface) {
        super.onDismiss(dialog)
        isOpenShow = false
    }

    override fun onDestroyView() {
        super.onDestroyView()
        handler?.removeCallbacksAndMessages(null)
        handler = null
    }


}